home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / rsynth1.zip / saynum.c < prev    next >
C/C++ Source or Header  |  1994-11-08  |  6KB  |  226 lines

  1. #include <config.h>
  2. /* $Id: saynum.c,v 1.13 1994/11/08 13:30:50 a904209 Exp a904209 $
  3.  */
  4. char *saynum_id = "$Id: saynum.c,v 1.13 1994/11/08 13:30:50 a904209 Exp a904209 $";
  5.  
  6. #include <stdio.h>
  7. #include "proto.h"
  8. #include "darray.h"
  9. #include "say.h"
  10.  
  11. /*
  12.    **              Integer to Readable ASCII Conversion Routine.
  13.    **
  14.    ** Synopsis:
  15.    **
  16.    **      say_cardinal(value)
  17.    **              long int     value;          -- The number to output
  18.    **
  19.    **      The number is translated into a string of words
  20.    **
  21.  */
  22. static char *Cardinals[] =
  23. {
  24.  "zero", "one", "two", "three",
  25.  "four", "five", "six", "seven",
  26.  "eight", "nine",
  27.  "ten", "eleven", "twelve", "thirteen",
  28.  "fourteen", "fifteen", "sixteen", "seventeen",
  29.  "eighteen", "nineteen"
  30. };
  31.  
  32.  
  33. static char *Twenties[] =
  34. {
  35.  "twenty", "thirty", "forty", "fifty",
  36.  "sixty", "seventy", "eighty", "ninety"
  37. };
  38.  
  39.  
  40. static char *Ordinals[] =
  41. {
  42.  "zeroth", "first", "second", "third",
  43.  "fourth", "fifth", "sixth", "seventh",
  44.  "eighth", "ninth",
  45.  "tenth", "eleventh", "twelfth", "thirteenth",
  46.  "fourteenth", "fifteenth", "sixteenth", "seventeenth",
  47.  "eighteenth", "nineteenth"
  48. };
  49.  
  50.  
  51. static char *Ord_twenties[] =
  52. {
  53.  "twentieth", "thirtieth", "fortieth", "fiftieth",
  54.  "sixtieth", "seventieth", "eightieth", "ninetieth"
  55. };
  56.  
  57. /*
  58.    ** Translate a number to phonemes.  This version is for CARDINAL numbers.
  59.    **       Note: this is recursive.
  60.  */
  61. unsigned
  62. xlate_cardinal(value, phone)
  63. long int value;
  64. darray_ptr phone;
  65. {
  66.  unsigned nph = 0;
  67.  if (value < 0)
  68.   {
  69.    nph += xlate_string("minus", phone);
  70.    value = (-value);
  71.    if (value < 0)                 /* Overflow!  -32768 */
  72.     {
  73.      nph += xlate_string("a lot", phone);
  74.      return nph;
  75.     }
  76.   }
  77.  if (value >= 1000000000L)
  78.   /* Billions */
  79.   {
  80.    nph += xlate_cardinal(value / 1000000000L, phone);
  81.    nph += xlate_string("billion", phone);
  82.    value = value % 1000000000;
  83.    if (value == 0)
  84.     return nph;                   /* Even billion */
  85.    if (value < 100)
  86.     nph += xlate_string("and", phone);
  87.    /* as in THREE BILLION AND FIVE */
  88.   }
  89.  if (value >= 1000000L)
  90.   /* Millions */
  91.   {
  92.    nph += xlate_cardinal(value / 1000000L, phone);
  93.    nph += xlate_string("million", phone);
  94.    value = value % 1000000L;
  95.    if (value == 0)
  96.     return nph;                   /* Even million */
  97.    if (value < 100)
  98.     nph += xlate_string("and", phone);
  99.    /* as in THREE MILLION AND FIVE */
  100.   }
  101.  
  102.  /* Thousands 1000..1099 2000..99999 */
  103.  /* 1100 to 1999 is eleven-hunderd to ninteen-hunderd */
  104.  if ((value >= 1000L && value <= 1099L) || value >= 2000L)
  105.   {
  106.    nph += xlate_cardinal(value / 1000L, phone);
  107.    nph += xlate_string("thousand", phone);
  108.    value = value % 1000L;
  109.    if (value == 0)
  110.     return nph;                   /* Even thousand */
  111.    if (value < 100)
  112.     nph += xlate_string("and", phone);
  113.    /* as in THREE THOUSAND AND FIVE */
  114.   }
  115.  if (value >= 100L)
  116.   {
  117.    nph += xlate_string(Cardinals[value / 100], phone);
  118.    nph += xlate_string("hundred", phone);
  119.    value = value % 100;
  120.    if (value == 0)
  121.     return nph;                   /* Even hundred */
  122.   }
  123.  if (value >= 20)
  124.   {
  125.    nph += xlate_string(Twenties[(value - 20) / 10], phone);
  126.    value = value % 10;
  127.    if (value == 0)
  128.     return nph;                   /* Even ten */
  129.   }
  130.  nph += xlate_string(Cardinals[value], phone);
  131.  return nph;
  132. }
  133.  
  134. /*
  135.    ** Translate a number to phonemes.  This version is for ORDINAL numbers.
  136.    **       Note: this is recursive.
  137.  */
  138. unsigned
  139. xlate_ordinal(value, phone)
  140. long int value;
  141. darray_ptr phone;
  142. {
  143.  unsigned nph = 0;
  144.  if (value < 0)
  145.   {
  146.    nph += xlate_string("minus", phone);
  147.    value = (-value);
  148.    if (value < 0)                 /* Overflow!  -32768 */
  149.     {
  150.      nph += xlate_string("a lot", phone);
  151.      return nph;
  152.     }
  153.   }
  154.  if (value >= 1000000000L)
  155.   /* Billions */
  156.   {
  157.    nph += xlate_cardinal(value / 1000000000L, phone);
  158.    value = value % 1000000000;
  159.    if (value == 0)
  160.     {
  161.      nph += xlate_string("billionth", phone);
  162.      return nph;                  /* Even billion */
  163.     }
  164.    nph += xlate_string("billion", phone);
  165.    if (value < 100)
  166.     nph += xlate_string("and", phone);
  167.    /* as in THREE BILLION AND FIVE */
  168.   }
  169.  
  170.  if (value >= 1000000L)
  171.   /* Millions */
  172.   {
  173.    nph += xlate_cardinal(value / 1000000L, phone);
  174.    value = value % 1000000L;
  175.    if (value == 0)
  176.     {
  177.      nph += xlate_string("millionth", phone);
  178.      return nph;                  /* Even million */
  179.     }
  180.    nph += xlate_string("million", phone);
  181.    if (value < 100)
  182.     nph += xlate_string("and", phone);
  183.    /* as in THREE MILLION AND FIVE */
  184.   }
  185.  
  186.  /* Thousands 1000..1099 2000..99999 */
  187.  /* 1100 to 1999 is eleven-hunderd to ninteen-hunderd */
  188.  if ((value >= 1000L && value <= 1099L) || value >= 2000L)
  189.   {
  190.    nph += xlate_cardinal(value / 1000L, phone);
  191.    value = value % 1000L;
  192.    if (value == 0)
  193.     {
  194.      nph += xlate_string("thousandth", phone);
  195.      return nph;                  /* Even thousand */
  196.     }
  197.    nph += xlate_string("thousand", phone);
  198.    if (value < 100)
  199.     nph += xlate_string("and", phone);
  200.    /* as in THREE THOUSAND AND FIVE */
  201.   }
  202.  if (value >= 100L)
  203.   {
  204.    nph += xlate_string(Cardinals[value / 100], phone);
  205.    value = value % 100;
  206.    if (value == 0)
  207.     {
  208.      nph += xlate_string("hundredth", phone);
  209.      return nph;                  /* Even hundred */
  210.     }
  211.    nph += xlate_string("hundred", phone);
  212.   }
  213.  if (value >= 20)
  214.   {
  215.    if ((value % 10) == 0)
  216.     {
  217.      nph += xlate_string(Ord_twenties[(value - 20) / 10], phone);
  218.      return nph;                  /* Even ten */
  219.     }
  220.    nph += xlate_string(Twenties[(value - 20) / 10], phone);
  221.    value = value % 10;
  222.   }
  223.  nph += xlate_string(Ordinals[value], phone);
  224.  return nph;
  225. }
  226.